package com.webSocket;  
  
import java.io.IOException;  
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.OnClose;  
import javax.websocket.OnError;  
import javax.websocket.OnMessage;  
import javax.websocket.OnOpen;  
import javax.websocket.Session;  
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;  


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
  
@ServerEndpoint(value = "/meeting/{param}")  
public class MeetingService {  
	// 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
	private static int onlineCount;
    private static final Map<String,MeetingService> connections = new ConcurrentHashMap<>(); 
    private Session session;
    private String role;
    private String socketId;
    public MeetingService() {  
    	
    }  
  

	@OnOpen  
    public synchronized void  start(@PathParam("param") String param,Session session) {
        this.session = session;
        String[] arr=param.split(",");
        this.role=param;
        this.socketId=arr[1];
        connections.put(role,this);  
        broadcast("{\"event\":\"msg\",\"data\":\""+role+"\"}",socketId);
        JSONArray array=new JSONArray();
        for (Entry<String, MeetingService> client  : connections.entrySet()) {
        	if(client.getValue().socketId.equals(socketId)||client.getValue().socketId==socketId){
        		array.add(client.getKey());
        	}
		}
		send("{\"event\":\"rolelist\",\"data\":"+array.toString()+"}", role,socketId);
		addOnlineCount(); // 在线数加
		System.out.println("有新连接加入！新用户："+role+",当前在线人数为" + getOnlineCount());
	}  
  
    @OnClose  
    public void end() {  
        connections.remove(role);  
        System.out.println(socketId);
        String msg=("{\"event\":\"role\",\"data\":\""+role+"\"}");
        broadcast(msg,socketId);
        subOnlineCount(); // 在线数减
		System.out.println("有一连接关闭！当前在线人数为" + getOnlineCount());
    }  
  
    @OnMessage  
    public void incoming(String message) {  
    	try {
        	JSONObject json=JSONObject.fromObject(message);
        	if(json.has("msg")){
        		broadcast(message,socketId);
        	}
        	if(json.has("to")){
                send(message,json.getString("to"),socketId);      		
        	}
        	String string = "";
    		String to = null;
    		if(json.has("message")){
    			 string = (String) json.get("message");
    		}
    		if(json.has("role")){
    			 to = (String) json.get("role");
    		}
    		send("{\"event\":\"message\",\"data\":\""+string+"\",\"from\":\""+role+"\"}",role,to,socketId);
		} catch (Exception e) {
			// TODO: handle exception
		
		}

    }  
  
    @OnError  
    public void onError(Throwable t) throws Throwable {  
        System.out.println("Chat Error: " + t.toString());  
    }  
    
    //发送给指定角色
    private static void send(String msg,String from,String to,String socketId){
      	try {
      		//to指定用户
      		MeetingService con = connections.get(to);
  			if(con!=null){
  				if(socketId==con.socketId||con.socketId.equals(socketId)){
  					con.session.getBasicRemote().sendText(msg);	
  				}
  	
  			}
  			//from具体用户
  			MeetingService confrom = connections.get(from);
  			if(confrom!=null){
  				if(socketId==confrom.socketId||confrom.socketId.equals(socketId)){
  					confrom.session.getBasicRemote().sendText(msg);	
  				}
  	
  			}
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
      }
    private static void send(String msg,String to,String socketId){
    	try {
			MeetingService con = connections.get(to);
			if(con!=null){
				if(socketId==con.socketId||con.socketId.equals(socketId)){
					con.session.getBasicRemote().sendText(msg);	
				}
	
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    private static void broadcast(String msg,String socketId) {  
		for (Entry<String, MeetingService> client : connections.entrySet()) {  
            try {  
                synchronized (client) {  
                	if(client.getValue().socketId==socketId||client.getValue().socketId.equals(socketId)){
                        client.getValue().session.getBasicRemote().sendText(msg); 	
                	}
         
                }  
            } catch (IOException e) {  
                System.out.println("Chat Error: Failed to send message to client");  
                connections.remove(client);  
                try {  
                	client.getValue().session.close();  
                } catch (IOException e1) {  
                    // Ignore  
                }  
                String message = String.format("* %s %s", client.getValue().role, " has been disconnected.");  
                broadcast(message,socketId);  
            }  
        }  
    }  
    public static synchronized int getOnlineCount() {
		return onlineCount;
	}

	public static synchronized void addOnlineCount() {
		MeetingService.onlineCount++;
	}

	public static synchronized void subOnlineCount() {
		MeetingService.onlineCount--;
	}
}  